﻿using System.Text;

namespace TPXSDK.NET.Mission.Instruction;

internal class InstTakeoff : Tokenizer
{
    public InstTakeoff(TokenizerAdmin admin)
    {
        Admin = admin;
        KeyName = "takeoff";
        Usage = "takeoff [alt][,altType]";
        KeyValue = (int)FlyCmdId.CMD_TAKEOFF;
        Description = @"takeoff :Performs a takeoff. All .fly files must include a takeoff command, even if the takeoff will be performed manually. The takeoff command supports runway takeoffs and hand, catapult, bungee, and car top launches.";
    }

    public override bool Process()
    {
        var flyCmp = Admin?.Compiler; if (null == flyCmp) return false;
        var tokens = flyCmp.GetLineTokens();
        if (null == tokens) return false;

        var cmd = new FlyCmdItem
        {
            Id = (byte)KeyValue,
            LineNum = tokens[0].Row
        };

        if (tokens.Count == 1)
        {
            cmd.P1 = (byte)ParaType.EMPTY;
            cmd.P2 = 0;
        }
        else if (tokens.Count == 2)
        {
            if (tokens[1].Type != TokenType.NUMBER) return false;
            cmd.P1 = (byte)ParaType.REL_POS;
            cmd.P2 = (short)Convert.ToDouble(tokens[1].Name);
            if (cmd.P2 > 32000 || cmd.P2 < 0)
            {
                flyCmp.ErrorMsg = $"{KeyName} Parameter is out range";
                return false;
            }
        }
        else if (tokens.Count == 3)
        {
            if (tokens[1].Type != TokenType.NUMBER) return false;
            if (tokens[2].Type != TokenType.NUMBER) return false;

            cmd.P2 = (short)Convert.ToDouble(tokens[1].Name);
            var altType = (byte)Convert.ToDouble(tokens[2].Name);
            cmd.P1 = (byte)(1 == altType ? ParaType.ABS_POS : ParaType.REL_POS);
        }
        else
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid Usage";
            return false;
        }
        flyCmp.CmdList.Add(cmd);
        return true;
    }

    public override void Reverse(FlyCmdItem cmd, StringBuilder sb)
    {
        var src = $"{KeyName} ?";
        if (cmd.P1 == (byte)ParaType.EMPTY)
        {
            src = KeyName;
        }
        else if (cmd.P1 == (byte)ParaType.REL_POS)
        {
            src = $"{KeyName} {cmd.P2}//m";
        }
        else if (cmd.P1 == (byte)ParaType.ABS_POS)
        {
            src = $"{KeyName} {cmd.P2},1//m";
        }
        sb.AppendLine(src);
    }
}

